/** 有待改进 **/

class Commitment {
    /* promise有三种状态 */
    static PENDING = '待定';
    static FULFILLED = '成功';
    static REJECTED = '拒绝';

    constructor(func) {
        //默认状态为待定状态
        this.status = Commitment.PENDING;
        //执行resolve或者reject时，会给result赋值
        this.result = null;

        //有一种情况就是创建promise实例时，将resolve或reject函数写在了setTimeout的回调函数里
        //这个时候手写promise的状态依然还是待定，需要回调保存。等resolve或reject执行了之后再执行then函数
        this.resolveCallbacks = [];
        this.rejectCallbacks = [];

        //使用try，catch是因为原生的promise可以在创建promise实例时，手动抛出异常
        try {
            //使用bind解决class的this指向问题
            func(this.resolve.bind(this), this.reject.bind(this));
        } catch (e) {
            this.reject(e);
        }
    }


    resolve(result) {
        /*resolve和reject是要在事件循环末尾执行的，所以使用了setTimeout*/
        setTimeout(() => {
            if (this.status === Commitment.PENDING) {
                this.status === Commitment.FULFILLED;
                this.result = result;
                this.resolveCallbacks.forEach(callback => {
                    callback(result);
                });
            }
        });
    }


    reject(result) {
        setTimeout(() => {
            if (this.status === Commitment.PENDING) {
                this.status = Commitment.REJECTED;
                this.result = result;
                this.rejectCallbacks.forEach(callback => {
                    callback(result);
                });
            }
        });
    }


    then(onFULFILLED, onREJECTED) {
        /*promise的链式功能，then后边可以then*/
        return new Commitment((resolve, reject) => {

            //如果传入参数不为函数，原生promise会忽略参数
            onFULFILLED = typeof onFULFILLED === 'function' ? onFULFILLED : () => {
            };
            onREJECTED = typeof onREJECTED === 'function' ? onREJECTED : () => {
            };

            if (this.status === Commitment.PENDING) {
                this.resolveCallbacks.push(onFULFILLED);
                this.rejectCallbacks.push(onREJECTED);
            }
            if (this.status === Commitment.FULFILLED) {
                setTimeout(() => {
                    onFULFILLED(this.result);
                });

            }
            if (this.status === Commitment.REJECTED) {
                setTimeout(() => {
                    onREJECTED(this.result);
                });
            }
        })

    }
}


/*测试*/
console.log("第一步");
let promise = new Commitment((resolve, reject) => {
    // throw new Error('出错了')
    console.log('第二步')
    setTimeout(() => {
        resolve('这次一定');
        // resolve后，reject不应该执行了，这个没有实现
        reject('下次一定');
        console.log('第四步');
    });
});

promise.then(result => {
    console.log(result)
}, result => {
    //如果是捕获reject,就应该这么捕获
    console.log(result)
    //如果是throw new Error()，就应该下边这么输出
    // console.log(result.message)
});
console.log('第三步');